interface ICommand {
  execute(): any;
}
// Command
class LightOnCommand implements ICommand {
  receiver: Light;
  constructor(re: Light) {
    this.receiver = re;
  }
  execute() {
    this.receiver.on();
  }
}

// received
class Light {
  on() {
    console.log(`开灯`);
  }
  off() {
    console.log(`关灯`);
  }
}

// invoker
class Invoker {
  command!: ICommand;
  // 这个方法用来设置插槽控制的命令
  setCommand(command: ICommand) {
    this.command = command;
  }
  // 当按钮按下时这个方法就会被调用
  buttonWasPressed() {
    this.command.execute(); // 使用当前命令衔接插槽，并调用它的 execute 方法
  }
}

// user
class User {
  // 这是一个使用命令模式的客户
  openLight(light: Light, remoteInvoker: Invoker) {
    // 它使用遥控器开灯
    // 生成将灯打开的命令
    let command = new LightOnCommand(light); // 生成一个打开客厅灯的命令
    // 然后将命令注入遥控器
    remoteInvoker.setCommand(command);
    // 按下遥控器的开关执行这个命令
    remoteInvoker.buttonWasPressed(); // 这样就可以执行任何命令了
  }
}

class main {
  run() {
    let remoteControl = new Invoker();
    // 新建灯
    let light = new Light();
    // 新建用户
    let user = new User();

    user.openLight(light, remoteControl); // 用遥控器开灯
  }
}

let t = new main();
t.run();

/**
 * 在集成终端打开此文件
 *
 * ts-node 0428.ts
 *
 */
